<template>
  <div class="ssh-wrap">
    <div class="ssh-header">
      {{host.hostname}} | {{host.username}}@{{host.ip}}:{{host.port}}
    </div>
    <div class="terminal">
      <div id="terminal"></div>
    </div>
  </div>
</template>

<script>
  import { Terminal } from 'xterm'
  import { FitAddon } from 'xterm-addon-fit'
  import 'xterm/css/xterm.css'
  import 'xterm/lib/xterm.js'
  import * as api from '@/api/main/host'
  import { mapGetters } from 'vuex'

  export default {
    data() {
      return {
        host: {},
        term: new Terminal(),
        container: null,
        socket: ''
      }
    },
    created() {
      this.getHostDetail()
      this.initXterm()
    },
    computed: {
      ...mapGetters(['token'])
    },
    methods: {
      getHostDetail() {
        api.getObj(this.$route.params.id).then(response => {
          this.host = response.data.data
        })
      },
      read_as_text(msg) {
        const reader = new window.FileReader()
        reader.readAsText(msg, 'utf-8')
        reader.onload = () => this.term.write(reader.result)
      },
      initXterm() {
        if (this.term) {
          this.term.dispose()
        }

        // 初始化一个终端界面容器
        this.term = new Terminal({
          rendererType: 'canvas', //渲染类型
          // rows: 50, //行
          convertEol: true, //启用时，光标将设置为下一行的开头
          scrollback: 1000, //终端中的回滚量
          tabStopWidth: 20, //制表宽度
          disableStdin: false, //是否应禁用输入
          cursorStyle: 'underline', //光标样式
          cursorBlink: true, //光标闪烁
          theme: {
            foreground: '#ffffff', //字体
            background: '#1f1b1b', //背景色
            cursor: 'help' //设置光标
          }
        })

        // 自适应屏幕大小
        const fitPlugin = new FitAddon()
        this.term.loadAddon(fitPlugin)

        // 连接websocket
        const wsUrl = this.getWsUrl()
        this.socket = new WebSocket(wsUrl)

        // 接收并渲染数据
        this.socket.onmessage = e => this.read_as_text(e.data)

        // 初始化界面
        this.socket.onopen = () => {
          this.term.open(document.getElementById('terminal'))
          this.term.focus()
          fitPlugin.fit()
        }

        // 关闭websocket
        this.socket.onclose = e => {
          if (e.code === 3333) {
            window.location.href = 'about:blank'
            window.close()
          } else {
            setTimeout(() => this.term.write('\r\nConnection is closed.\r\n'), 200)
          }
        }

        // 向服务器发送数据
        this.term.onData(data => {
          //这里key值是你输入的值，数据格式order一定要找后端要！！！！
          let order = {
            data: data
          }
          this.socket.send(JSON.stringify(order))
        })

        console.log(this.term.cols, this.term.rows, 111111111111)
        // 检测屏幕大小改变终端大小
        this.term.onResize(({ cols, rows }) => {
          console.log(cols, rows)
          this.socket.send(JSON.stringify({ resize: [cols, rows] }))
        })
        window.onresize = () => fitPlugin.fit()
      },
      // 获取websocket连接地址
      getWsUrl() {
        const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'
        const urlFamily = window.location.host.split(':')
        const hostname = urlFamily[0] // "192.168.0.20";
        let urlPort = urlFamily.length === 2 ? Number(urlFamily[1]) : null
        if (urlPort === 81) {
          urlPort = 9001
        }
        return `${protocol}//${hostname}${urlPort ? ':' + urlPort : ''}${urlPort !== 9001 ? '/api' : ''}/ws/ssh/${this.$route.params.id}/?x-token=${this.token}`
      }
    }
  }

</script>

<style scoped>
  .ssh-wrap {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
  }


  .ssh-header {
    height: 46px;
    font-size: 17px;
    color: #ffffff;
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0 10px;
    background-color: #3a3333;
  }

  .actions {
    display: flex;
    align-items: center;
  }

  .terminal {
    flex: 1;
    display: flex;
    background-color: #000;
    padding-left: 5px;
  }

  .terminal > div {
    flex: 1
  }
</style>